package com.tiancheng.trade.settlement.service.settlement.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tiancheng.trade.commom.core.data.PageInfo;
import com.tiancheng.trade.commom.core.utils.DateTimeUtil;
import com.tiancheng.trade.settlement.enums.OrderSourceEnum;
import com.tiancheng.trade.settlement.enums.PaymentChannelEnum;
import com.tiancheng.trade.settlement.enums.SettlementBillDataExceptionEnum;
import com.tiancheng.trade.settlement.enums.SettlementBillDataExceptionTypeEnum;
import com.tiancheng.trade.settlement.mapper.settlement.SettlementBillDataMapper;
import com.tiancheng.trade.settlement.mapper.settlement.SettlementWaitBillQueryMapper;
import com.tiancheng.trade.settlement.model.settlement.SettlementBillData;
import com.tiancheng.trade.settlement.service.settlement.ISettlementBillDataAdminService;
import com.tiancheng.trade.settlement.util.ExcelUtil;
import com.tiancheng.trade.settlement.util.ObjectConvertUtil;
import com.tiancheng.trade.settlement.vo.settlement.admin.SettlementBillDataQueryVO;
import com.tiancheng.trade.settlement.vo.settlement.admin.res.SettlementBillDataExportResVO;
import com.tiancheng.trade.settlement.vo.settlement.admin.res.SettlementBillDataResVO;
import com.tiancheng.trade.settlement.vo.settlement.admin.res.SuccessBillResVO;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 清分待对账单
 */
@Service
public class SettlementBillDataAdminService implements ISettlementBillDataAdminService {

    @Autowired
    private SettlementBillDataMapper settlementBillDataMapper;

    @Autowired
    SettlementWaitBillQueryMapper settlementWaitBillQueryMapper;

    /**
     * 获取查询条件
     *
     * @param settlementBillDataQueryVO
     * @return
     */
    private QueryWrapper<SettlementBillData> getCondition(SettlementBillDataQueryVO settlementBillDataQueryVO) {
        QueryWrapper<SettlementBillData> conditions = new QueryWrapper<>();
        if (StringUtils.isNotBlank(settlementBillDataQueryVO.getSubOrderId())) {
            conditions.eq("sub_order_id", settlementBillDataQueryVO.getSubOrderId());
        }
        if (StringUtils.isNotBlank(settlementBillDataQueryVO.getOrderId())) {
            conditions.eq("order_id", settlementBillDataQueryVO.getOrderId());
        }
        if (StringUtils.isNotBlank(settlementBillDataQueryVO.getMerchantName())) {
            conditions.likeRight("merchant_name", settlementBillDataQueryVO.getMerchantName());
        }
        if (StringUtils.isNotBlank(settlementBillDataQueryVO.getClearRuleCode())) {
            conditions.eq("clear_rule_code", settlementBillDataQueryVO.getClearRuleCode());
        }
        if (StringUtils.isNotBlank(settlementBillDataQueryVO.getRuleName())) {
            conditions.eq("rule_name", settlementBillDataQueryVO.getRuleName());
        }
        if (settlementBillDataQueryVO.getOrderSource() != null) {
            conditions.eq("order_source", settlementBillDataQueryVO.getOrderSource());
        }
        if (settlementBillDataQueryVO.getPayTimeBegin() != null) {
            conditions.ge("pay_time", settlementBillDataQueryVO.getPayTimeBegin());
        }
        if (settlementBillDataQueryVO.getPayTimeEnd() != null) {
            conditions.le("pay_time", settlementBillDataQueryVO.getPayTimeEnd());
        }
        if (settlementBillDataQueryVO.getVerifiedTimeBegin() != null) {
            conditions.ge("verified_time", settlementBillDataQueryVO.getVerifiedTimeBegin());
        }
        if (settlementBillDataQueryVO.getVerifiedTimeEnd() != null) {
            conditions.le("verified_time", settlementBillDataQueryVO.getVerifiedTimeEnd());
        }
        if (settlementBillDataQueryVO.getShouldClearDateBegin() != null) {
            conditions.ge("should_clear_date", settlementBillDataQueryVO.getShouldClearDateBegin());
        }
        if (settlementBillDataQueryVO.getShouldClearDateEnd() != null) {
            conditions.le("should_clear_date", settlementBillDataQueryVO.getShouldClearDateEnd());
        }
        if (StringUtils.isNotBlank(settlementBillDataQueryVO.getIsException())) {
            conditions.eq("is_exception", settlementBillDataQueryVO.getIsException());
            String isException = settlementBillDataQueryVO.getIsException();
            if (isException.equals(SettlementBillDataExceptionEnum.YES.getCode())) {
                conditions.and(wrapper -> wrapper.eq("exception_type", SettlementBillDataExceptionTypeEnum.RULE_MISSING.getCode())
                        .or((wrapper2 -> wrapper2.eq("exception_type", SettlementBillDataExceptionTypeEnum.AMOUNT_ABNORMAL.getCode())
                                .in("sub_order_id", "SELECT sub_order_id FROM settlement_wait_bill WHERE is_delete=0 AND bill_status='wait' "))));
            } else if (isException.equals(SettlementBillDataExceptionEnum.NO.getCode())) {
                //todo 经确认，只需要sub_order_id就可以关联，但还是要用真实的数据进行验证
                conditions.in("sub_order_id", "SELECT sub_order_id FROM settlement_wait_bill WHERE is_delete=0 AND bill_status='wait' ");
            }
        }
        if (StringUtils.isNotBlank(settlementBillDataQueryVO.getProductCode())) {
            conditions.eq("product_code", settlementBillDataQueryVO.getProductCode());
        }
        return conditions;
    }

    /**
     * 分页查询
     *
     * @param settlementBillDataQueryVO 查询条件
     * @return
     */
    @Override
    public PageInfo queryBatchBillList(SettlementBillDataQueryVO settlementBillDataQueryVO) {
        Page<SuccessBillResVO> page = new Page<>();
        page.setCurrent(settlementBillDataQueryVO.getCurrentPage());
        page.setSize(settlementBillDataQueryVO.getPageSize());

        IPage<SettlementBillDataResVO> pageResult = settlementWaitBillQueryMapper.queryBatchBillList(page, settlementBillDataQueryVO);
        PageInfo.Pagination pagination = new PageInfo.Pagination(settlementBillDataQueryVO.getCurrentPage(), settlementBillDataQueryVO.getPageSize(), page.getTotal());
        List<SettlementBillDataResVO> list = pageResult.getRecords();
        for (SettlementBillDataResVO settlementBillData : list) {
            settlementBillData.setPayChannelCodeCn(PaymentChannelEnum.getDesc(settlementBillData.getPayChannelCode()));
            settlementBillData.setOrderSourceCn(OrderSourceEnum.getDesc(settlementBillData.getOrderSource()));
        }
        return new PageInfo<>(list, pagination);
    }

    /**
     * 分页查询 清分待对帐单/待对帐异常-列表
     *
     * @param settlementBillDataQueryVO 查询条件
     * @return
     */
    @Override
    public PageInfo findPageList(SettlementBillDataQueryVO settlementBillDataQueryVO) {
        Page<SuccessBillResVO> page = new Page<>();
        page.setCurrent(settlementBillDataQueryVO.getCurrentPage());
        page.setSize(settlementBillDataQueryVO.getPageSize());

        IPage<SettlementBillDataResVO> pageResult = settlementWaitBillQueryMapper.querySettlementWaitBillList(page, settlementBillDataQueryVO);
        PageInfo.Pagination pagination = new PageInfo.Pagination(settlementBillDataQueryVO.getCurrentPage(), settlementBillDataQueryVO.getPageSize(), page.getTotal());
        List<SettlementBillDataResVO> list = pageResult.getRecords();
        for (SettlementBillDataResVO settlementBillData : list) {
            settlementBillData.setPayChannelCodeCn(PaymentChannelEnum.getDesc(settlementBillData.getPayChannelCode()));
            settlementBillData.setOrderSourceCn(OrderSourceEnum.getDesc(settlementBillData.getOrderSource()));
        }
        return new PageInfo<>(list, pagination);
    }


    /**
     * 导出
     *
     * @param settlementBillDataQueryVO 查询条件
     * @param request
     * @param response
     * @throws IOException
     */
    @Override
    public void export(SettlementBillDataQueryVO settlementBillDataQueryVO, HttpServletRequest request, HttpServletResponse response) throws IOException {
        QueryWrapper<SettlementBillData> conditions = getCondition(settlementBillDataQueryVO);
        List<SettlementBillData> list = settlementBillDataMapper.selectList(conditions);
        List<SettlementBillDataExportResVO> listRes = new ArrayList<>();
        for (SettlementBillData settlementBillData : list) {
            SettlementBillDataExportResVO res = ObjectConvertUtil.convert(settlementBillData, SettlementBillDataExportResVO.class).get();
            res.setPayChannelCode(PaymentChannelEnum.getDesc(settlementBillData.getPayChannelCode()));
            res.setOrderSource(OrderSourceEnum.getDesc(settlementBillData.getOrderSource()));
            Integer clearingCycleValue = settlementBillData.getClearingCycleValue();
            res.setClearingCycleValue("t+" + clearingCycleValue);
            BigDecimal verifiedAmount = new BigDecimal(settlementBillData.getVerifiedAmount());
            res.setVerifiedAmount(verifiedAmount.divide(new BigDecimal(100)).toString());
            res.setPayTime(DateTimeUtil.format(settlementBillData.getPayTime(), "yyyy-MM-dd HH:mm:ss"));
            res.setVerifiedTime(DateTimeUtil.format(settlementBillData.getVerifiedTime(), "yyyy-MM-dd HH:mm:ss"));
            res.setShouldClearDate(DateTimeUtil.format(settlementBillData.getShouldClearDate(), "yyyy-MM-dd"));
            listRes.add(res);
        }
        List<Map<String, Object>> mapList = listConvert(listRes);
        String fileName = "SettlementBillData.xlsx";
        String[] title = {"子订单号 ", "主订单号", "商品名称", "商品编码", "商品类型", "商户名称", "商户编码", "清分渠道", "清分金额", "规则编码", "交易时间", "核销时间", "清分周期", "应清出日期"};
        Workbook workbook = ExcelUtil.buildWorkbook("清分待对账单", title, mapList);
        ExcelUtil.exportExcle(request, response, workbook, fileName);
    }

    /**
     * 数据转换
     *
     * @param list 清分待对账数据
     * @return
     */
    private List<Map<String, Object>> listConvert(List<SettlementBillDataExportResVO> list) {
        List<Map<String, Object>> list_map = new ArrayList<>();
        try {
            for (SettlementBillDataExportResVO t : list) {
                Field[] fields = t.getClass().getDeclaredFields();
                Map<String, Object> m = new LinkedHashMap<>();
                for (Field field : fields) {
                    String keyName = field.getName();
                    PropertyDescriptor pd = new PropertyDescriptor(keyName, t.getClass());
                    Method getMethod = pd.getReadMethod();// 获得getter方法
                    Object o = getMethod.invoke(t);// 执行get方法返回一个Object
                    m.put(keyName, o);
                }
                list_map.add(m);
            }
            return list_map;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
